package com.gitee.linmt.service.impl;

import com.gitee.linmt.entity.Permission;
import com.gitee.linmt.entity.RolePermission;
import com.gitee.linmt.repository.PermissionRepository;
import com.gitee.linmt.service.PermissionService;
import com.gitee.linmt.service.RolePermissionService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author linmt
 */
@Service
public class PermissionServiceImpl implements PermissionService {

    private final PermissionRepository permissionRepository;
    private final RolePermissionService rolePermissionService;

    public PermissionServiceImpl(PermissionRepository permissionRepository, RolePermissionService rolePermissionService) {
        this.permissionRepository = permissionRepository;
        this.rolePermissionService = rolePermissionService;
    }

    @Override
    public Map<Integer, List<Permission>> listByRoleIds(Collection<Integer> roleIds) {
        Map<Integer, List<Permission>> roleIdToPermissions = new HashMap<>();
        if (CollectionUtils.isEmpty(roleIds)) {
            return roleIdToPermissions;
        }
        List<RolePermission> rolePermissions = rolePermissionService.listByRoleIds(roleIds);
        if (CollectionUtils.isEmpty(rolePermissions)) {
            return roleIdToPermissions;
        }
        Set<Integer> permissionIds = new HashSet<>();
        Map<Integer, List<Integer>> roleIdToPermissionIds = new HashMap<>();
        for (RolePermission rolePermission : rolePermissions) {
            permissionIds.add(rolePermission.getPermissionId());
            List<Integer> permissionIdsOrDefault =
                    roleIdToPermissionIds.getOrDefault(rolePermission.getRoleId(), new ArrayList<>());
            permissionIdsOrDefault.add(rolePermission.getPermissionId());
            roleIdToPermissionIds.put(rolePermission.getRoleId(), permissionIdsOrDefault);
        }
        Map<Integer, Permission> idToPermission =
                permissionRepository.findAllById(permissionIds).stream().collect(Collectors.toMap(Permission::getId, p -> p));
        for (Map.Entry<Integer, List<Integer>> entry : roleIdToPermissionIds.entrySet()) {
            List<Permission> permissions = new ArrayList<>();
            for (Integer permissionId : entry.getValue()) {
                permissions.add(idToPermission.get(permissionId));
            }
            roleIdToPermissions.put(entry.getKey(), permissions);
        }
        return roleIdToPermissions;
    }
}
